# -*- coding: utf-8 -*-

# dialogs/scan.py

# Copyright 2009-2010 Diego Hansen Hahn (aka DiegoHH) <diegohh90 [at] hotmail [dot] com>

# lazynds is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License.

# lazynds is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with lazynds. If not, see <http://www.gnu.org/licenses/>.

import heapq
import os
import time
import threading
import mmap

import gtk

import default

class Scan:

    def __init__(self, builder, parent, bios):
        self.builder = builder

        self.dialog = self.builder.get_object('scan_dialog')
        self.dialog.set_transient_for(parent)

        self.progbar = self.builder.get_object('progbar')
        self.minsize = self.builder.get_object('minsize')
        self.maxsize = self.builder.get_object('maxsize')
#        self.maxsearch= self.builder.get_object('maxsearch')
#        self.maxsearch.connect('toggled', self.on_maxsearch_toggled)

        self.bios = bios

#     OBSOLETO +2.0.4
#    def on_maxsearch_toggled(self, widget):
#        # Compatibilidade. Tirar no final - Hansen
#        if widget.get_active():
#            setattr(self.bios, 'MULTIPLE', 1)
#        else:
#            setattr(self.bios, 'MULTIPLE', 32)
#
#        setattr(self.bios, 'MAX_SEARCH', widget.get_active())

    def run(self, fmap, _bios_list, _plugin_list):
        self.minsize.set_adjustment(adjustment = gtk.Adjustment(0x20, 0x20, 0x7FFFF, 0xFF, 0xFFF, 0))
        self.maxsize.set_adjustment(adjustment = gtk.Adjustment(0xFFFF, 0x20, 0x7FFFF, 0xFF, 0xFFF, 0))

        self.progbar.set_text("Aguardando ...")
        self.progbar.set_fraction(0.0)

        while True:
            if self.dialog.run() == gtk.RESPONSE_OK:
                self.dialog.set_sensitive(False)

                minsize = self.minsize.get_value_as_int()
                maxsize = self.maxsize.get_value_as_int()
#                maxsearch = self.maxsearch.get_active()

                if minsize >= maxsize:
                    default.Error(self.dialog, "O valor máximo deve ser maior que o mínimo.")
                    go = False
                else:
                    setattr(self.bios, 'MIN_SIZE', minsize)
                    setattr(self.bios, 'MAX_SIZE', maxsize)
                    go = True

                if go:
                    if not (_bios_list.active_list or _plugin_list.active_list):
                        default.Error(self.dialog, 'Nenhuma opção de busca escolhida.')

                    else:
                        fs = ProgBarThread(progbar = self.progbar, fmap = fmap)
                        fs.start()
                        self.progbar.set_text('Buscando dados comprimidos ...')
                        # Inicia a atualização da barra de progresso para as rotinas da bios
                        if _bios_list.active_list:
                            fs.go()
                            setattr(self.bios, 'compressions', _bios_list.active_list)
                            self.bios.bios_scan(fmap)
                            fs.stop()

                            self.progbar.set_fraction(1.0)
                            self.progbar.set_text('Concluído')

                            while gtk.events_pending():
                                gtk.main_iteration()

                        if _plugin_list.active_list:
                            for plugin in _plugin_list.active_list:
                                self.progbar.set_text("Usando plugin %s ..." % plugin)
                                fs.go()
                                self.bios.plugin_scan(fmap, plugin)
                                fs.stop()

                                self.progbar.set_fraction(1.0)
                                self.progbar.set_text("Concluído!")

                                while gtk.events_pending():
                                    gtk.main_iteration()

                        time.sleep(0.5) #Aguarda 0.5ms antes de fechar a janela

                        self.dialog.hide()
                        self.dialog.set_sensitive(True)
                        return True
                self.dialog.set_sensitive(True)

            else:
                self.dialog.hide()
                self.dialog.set_sensitive(True)
                return False


class ProgBarThread(threading.Thread):
    ''' Thread exclusiva para atualização da barra de progresso '''
    stopthread = threading.Event()

    def __init__(self, *args, **kwargs):
        threading.Thread.__init__(self)

        self.progbar = kwargs['progbar']
        self.fmap = kwargs['fmap']

    def run(self):
        self.stopthread.clear()
        self.progbar.set_fraction(0.0)
        while not self.stopthread.is_set():
            try:
                self.stopthread.clear()
                percent = float(self.fmap.tell())/self.fmap.size()
                self.progbar.set_fraction(percent)
            except:
                break

    def stop(self):
         self.stopthread.set()

    def go(self):
        self.stopthread.clear()
